package com.hula.onion.book.server.dao.impl;

import com.hula.onion.book.server.config.ChannelConfig;
import com.hula.onion.book.server.dao.IUserDao;
import com.hula.onion.book.server.model.User;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

/**
 * Created by shan on 18/1/24.
 */
@Repository
public class UserDaoImpl extends JdbcDaoSupport implements IUserDao {
    private static final BeanPropertyRowMapper<User> mapper =
            new BeanPropertyRowMapper<>(User.class);

    @Resource(name = "dataSource")
    private DataSource dataSource;

    UserDaoImpl(DataSource dataSource) {
        setDataSource(dataSource);
    }

    private static final String GET_USER_BY_OPEN_ID = "select * from user where ";

    @Override
    public User getUserByOpendId(String openId, int source) {
        String sourceOpenId = null;
        if (ChannelConfig.WECHAT.getValue() == source) {
            sourceOpenId = "wx_openid=?;";
        } else if (ChannelConfig.QQ.getValue() == source) {
            sourceOpenId = "qq_openid=?;";
        }
        List<User> result = this.getJdbcTemplate().query(GET_USER_BY_OPEN_ID + sourceOpenId,
                new Object[]{openId}, mapper);
        if (CollectionUtils.isNotEmpty(result)) {
            return result.get(0);
        }
        return null;
    }

    private static final String UPDATE_WX_USER = "update user set wx_nick_name=?,wx_head_pic=? where id=?";

    private static final String UPDATE_QQ_USER = "update user set qq_nick_name=?,qq_head_pic=? where id=?";

    @Override
    public boolean updateUser(String nickName, String headPic, int userId, int source) {
        String execute_sql = null;
        if (ChannelConfig.WECHAT.getValue() == source) {
            execute_sql = UPDATE_WX_USER;
        } else if (ChannelConfig.QQ.getValue() == source) {
            execute_sql = UPDATE_QQ_USER;
        }
        return 1 == this.getJdbcTemplate().update(execute_sql, new Object[]{nickName, headPic, userId});
    }


    private static final String REGISTER_USER_BY_WX = "insert into user(wx_nick_name,wx_head_pic, wx_openid,channel_id) values (?,?,?,?)";

    private static final String REGISTER_USER_BY_QQ = "insert into user(qq_nick_name,qq_head_pic, qq_openid,channel_id) values (?,?,?,?)";

    @Override
    public int register(final String nickName, final String headPic, final String openId, final int source) {
        KeyHolder keyHolder = new GeneratedKeyHolder();
        this.getJdbcTemplate().update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection con)
                    throws SQLException {
                String execute_register = null;
                if (ChannelConfig.WECHAT.getValue() == source) {
                    execute_register = REGISTER_USER_BY_WX;
                } else if (ChannelConfig.QQ.getValue() == source) {
                    execute_register = REGISTER_USER_BY_QQ;
                }
                PreparedStatement ps = con.prepareStatement(execute_register, Statement.RETURN_GENERATED_KEYS);
                ps.setString(1, nickName);
                ps.setString(2, headPic);
                ps.setString(3, openId);
                ps.setInt(4, source);
                return ps;
            }
        }, keyHolder);
        return keyHolder.getKey().intValue();
    }

    private static final String REGISTER_USER = "insert into user(phone,password,channel_id) values (?,?,?)";

    @Override
    public boolean register(String phone, String password) {
        return 1 == this.getJdbcTemplate().update(REGISTER_USER, new Object[]{phone, password, 1});
    }

    private static final String UPDATE_PWD = "update user set password=? where phone=?";

    @Override
    public boolean updatePassword(String phone, String newPassword) {
        return 1 == this.getJdbcTemplate().update(UPDATE_PWD,
                new Object[]{newPassword, phone});
    }

    private static final String CHANGE_PWD_BY_UID = "update user set password=? where id=?";

    @Override
    public boolean changePasswordByUid(int userId, String newPassword) {
        return 1 == this.getJdbcTemplate().update(CHANGE_PWD_BY_UID,
                new Object[]{newPassword, userId});
    }

    private static final String GET_PWD_BY_UID = "select password from user " +
            "where id=?";

    @Override
    public String getPasswordByUid(int userId) {
        return this.getJdbcTemplate().queryForList(
                GET_PWD_BY_UID, new Object[]{userId},
                String.class).get(0);
    }

    private static final String BIND_PHONE_BY_UID = "update user set phone=?, password=? where id=?";

    @Override
    public boolean bindPhone(int userId, String mobile, String password) {
        return 1 == this.getJdbcTemplate().update(BIND_PHONE_BY_UID,
                new Object[]{mobile, password, userId});
    }

    private static final String BIND_WX = "update user set wx_openid=?,wx_nick_name=?,wx_head_pic=? where id=?;";

    private static final String BIND_QQ = "update user set qq_openid=?,qq_nick_name=?,qq_head_pic=? where id=?;";

    @Override
    public boolean bindThird(int userId, String openId, String nickName, String headPic, int source) {
        String execute_sql = null;
        if (ChannelConfig.WECHAT.getValue() == source) {
            execute_sql = BIND_WX;
        } else if (ChannelConfig.QQ.getValue() == source) {
            execute_sql = BIND_QQ;
        }
        return 1 == this.getJdbcTemplate().update(execute_sql, new Object[]{openId, nickName, headPic, userId});
    }

    private static final String GET_USER_BY_MOBILE = "select * from user where phone=?";

    @Override
    public User getUserByMobile(String mobile) {
        List<User> result = this.getJdbcTemplate().query(GET_USER_BY_MOBILE,
                new Object[]{mobile}, mapper);
        if (CollectionUtils.isNotEmpty(result)) {
            return result.get(0);
        }
        return null;
    }

    private static final String GET_USER_BY_ID = "select * from user where id=?";

    @Override
    public User getUserByUserId(int userId) {
        List<User> result = this.getJdbcTemplate().query(GET_USER_BY_ID,
                new Object[]{userId}, mapper);
        if (CollectionUtils.isNotEmpty(result)) {
            return result.get(0);
        }
        return null;
    }


    private static final String MOBILE_EXIST = "select count(*) from user where phone=?";

    @Override
    public boolean mobileExist(String phone) {
        return 1 == this.getJdbcTemplate().queryForObject(MOBILE_EXIST,
                new Object[]{phone}, Integer.class);
    }

    private static final String FEED_BACK = "insert into feedback(user_id,content) values (?,?)";

    @Override
    public boolean createFeedBack(int userId, String message) {
        return 1 == this.getJdbcTemplate().update(FEED_BACK,
                new Object[]{userId, message});
    }

}
